iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
Software Development

做一支專屬自己學校的課程評價 LINE Bot 吧!系列 第 17

[Day 17] 簡易前端框架 Bootstrap 5 製作評價瀏覽網頁 (下)

  • 分享至 

  • xImage
  •  

評價顯示部分

在網頁的第二部分,因為重複的 HTML 會一直出沒,會以迴圈為核心進行編寫:
評價顯示

在這裡會用到幾個很重要的觀念:

Variable tag 變數標籤 {{ }}

在上一篇有提到 {{ }} 是一種 Django 所特有的 Variable tag,兩個花括號代表的是一個變數,在之後會密集的出現這類型的 tag,目的讓由後端傳值至前端時能動態代入至 HTML。
例如:

<div class="card-footer text-muted">
投稿:{{ each_feedback.submitter_name }} {{ each_feedback.last_updated_time }}
</div>

Template tag 語法/模板標籤 {% %}

{% %} 則是 Template tag 語法/模板標籤,因 HTML 不具有邏輯設計,常被調侃不是程式語言,可以加入 for 迴圈或 if 條件句根據情況顯示的 HTML 內容。
例如:

{% for each_feedback in feedback %}
    <!-- 每則評價的 HTML -->
{% endfor %}

for loog Template tag 迴圈特有標籤

如果使用了 {% for each_feedback in feedback %} 搭配 {% endfor %} 進行迴圈的 HTML 呈現,就能夠使用 {{forloop.counter}}去判斷現在是第 N 個元素,能夠當作 id 屬性進行後續 Js 處理。而當變數內其實沒有內容時, {% empty %} 也可以作為無內容的 HTML 顯示。
例如:

{% for each_feedback in feedback %}
    <span class="collapse" id="collapse-each_feedback-{{ forloop.counter }}">
    <!-- 每則評價的 HTML -->
    {% empty %}
    <p class="text-center">沒有符合的評價結果。</p>
{% endfor %}

Template filters 模板過濾器 |

模板過濾器也是很酷的功能,若是變數很長 (像是評價肉肉長),就能使用 | slice:":200"| slice:"200:" 顯示前 200 字或後 200 字,適合用於展開折疊內容用途。| linebreaksbr 會將文本中的換行符 \n 替換為 <br /> 標籤,這樣換行符在 HTML 中會正確顯示為換行效果。
例如要將評價內容顯示後 200 字:

{{ each_feedback.feedback_content|slice:"200:"|linebreaksbr }}

Bootstrap Icons

Bootstrap 也提供 Icons 庫可以讓開發者選擇不一樣酷酷的圖案,除了以字體方式引入 Icon 外,也能使用 SVG 方式貼上:

<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-arrows-expand" viewBox="0 0 16 16">
    <path fill-rule="evenodd"
    d="M1 8a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13A.5.5 0 0 1 1 8M7.646.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 1.707V5.5a.5.5 0 0 1-1 0V1.707L6.354 2.854a.5.5 0 1 1-.708-.708zM8 10a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L7.5 14.293V10.5A.5.5 0 0 1 8 10" />
</svg>

完整的評價顯示內容:

<!-- 使用 Django template tag 顯示單頁最多十則評價 -->
<div class="row">
    <!-- 利用迴圈顯示後端 feedback 所含有的各個課程資訊 -->
    {% for each_feedback in feedback %}
    <div class="col-md-4 mt-3 d-flex">
        <div class="card mb-4 h-100">
            <div class="card-header">
            
                <!-- 顯示單一個 each_feedback 的特定內容 -->
            {{ each_feedback.teacher_name }}-{{ each_feedback.course_name }}
            </div>
            <div class="card-body">

                <p class="card-text">
                
                    <!-- 甚至可以決定顯示前 200 個字元,並允許以 br 換行 -->
                {{ each_feedback.feedback_content|slice:":200"|linebreaksbr }}
                    
                    <!-- forloop.counter 能提示出目前的元素是第幾個 -->
                <span class="collapse" id="collapse-each_feedback-{{ forloop.counter }}">
                        {{ each_feedback.feedback_content|slice:"200:"|linebreaksbr }}
                </p>
                <button type="button" class="btn btn-sm btn-light" data-bs-toggle="collapse"
                href="#collapse-each_feedback-{{ forloop.counter }}" role="button" aria-expanded="false"
                aria-controls="collapse-each_feedback-{{ forloop.counter }}">
                
                <!-- 這邊看起來像是亂碼的地方,其實是一個折疊的 icon -->
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
                    class="bi bi-arrows-expand" viewBox="0 0 16 16">
                    <path fill-rule="evenodd"
                        d="M1 8a.5.5 0 0 1 .5-.5h13a.5.5 0 0 1 0 1h-13A.5.5 0 0 1 1 8M7.646.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 1.707V5.5a.5.5 0 0 1-1 0V1.707L6.354 2.854a.5.5 0 1 1-.708-.708zM8 10a.5.5 0 0 1 .5.5v3.793l1.146-1.147a.5.5 0 0 1 .708.708l-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 0 1 .708-.708L7.5 14.293V10.5A.5.5 0 0 1 8 10" />
                </svg>
            </button>
            </div>

            <div class="card-footer text-muted">
                投稿:{{ each_feedback.submitter_name }} {{ each_feedback.last_updated_time }}
            </div>
        </div>
    </div>
    <!-- 當 for 迴圈發現內容為空時,則顯示無評價結果 -->
    {% empty %}
    <p class="text-center">沒有符合的評價結果。</p>
    {% endfor %}
</div>

分頁部分

分頁

paginator 模板標籤

當後端以 Django 的 Paginator 使用時,前端就能以 paginator 模板標籤搭配 {% if %} {% endif %}{% for %} {% endfor %} 進行渲染:

  • has_previous:如果當前頁面有上一頁,返回 True。
  • has_next:如果當前頁面有下一頁,返回 True。
  • previous_page_number:返回上一頁的頁碼。
  • next_page_number:返回下一頁的頁碼。
  • number:返回當前頁面的頁碼。
  • paginator.num_pages:返回總頁數。
  • paginator.page_range:範圍是從 1 到總頁數
<!-- 分頁按鈕 -->
<nav aria-label="Page navigation example">
    <ul class="pagination justify-content-center">
        {% if feedback.has_previous %}
        <li class="page-item">
            <a class="page-link" href="?page={{ feedback.previous_page_number }}" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
            </a>
        </li>
        {% endif %}
        {% for num in feedback.paginator.page_range %}
        <li class="page-item mt-3 {% if feedback.number == num %}active{% endif %}">
            <a class="page-link" href="?page={{ num }}">{{ num }}</a>
        </li>
        {% endfor %}
        {% if feedback.has_next %}
        <li class="page-item">
            <a class="page-link" href="?page={{ feedback.next_page_number }}" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
            </a>
        </li>
        {% endif %}
    </ul>
</nav>

覆盤

在這篇文章中,我們學會了:

  • Variable tag 變數標籤
  • Template tag 語法/模板標籤
  • For loop Template tag 迴圈特有標籤
  • Paginator Template tag 模板標籤
  • Bootstrap Icons 的引入

上一篇
[Day 16] 簡易前端框架 Bootstrap 5 製作評價瀏覽網頁 (中)
下一篇
[Day 18] LINE Bot 回覆加上 Loading Animation 思考載入動畫 (V3.11.0)
系列文
做一支專屬自己學校的課程評價 LINE Bot 吧!21
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言